using AutoMapper;
using B.S.NewMedical.Api.Read.Application.Command.Doctor;
using B.S.NewMedical.Api.Read.DTOS.Doctor;
using B.S.NewMedical.Domain.Appointment;
using B.S.NewMedical.Domain.Doctor;
using B.S.NewMedical.Domain.Hospital;
using B.S.NewMedical.ErrorCode;
using B.S.NewMedical.Infrastructure.Interface;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.NewMedical.Api.Read.Application.Handler.Doctor
{
    /// <summary>
    /// 获取医生列表处理器
    /// </summary>
    public class GetDoctorsHandler : IRequestHandler<GetDoctorsCommand, ApiPageing<DoctorDto>>
    {
        private readonly IBaseRepository<Domain.Appointment.Doctor> _doctorRepository;
        private readonly IBaseRepository<DepartmentModel> _departmentRepository;
        private readonly IBaseRepository<JobTitleModel> _jobTitleRepository;
        private readonly IBaseRepository<HospitalModel> _hospitalRepository;
        private readonly IBaseRepository<HospitalDepartmentModel> _hospitalDepartmentRepository;
        private readonly ILogger<GetDoctorsHandler> _logger;
        private readonly IMapper _mapper;

        public GetDoctorsHandler(
            IBaseRepository<Domain.Appointment.Doctor> doctorRepository,
            IBaseRepository<DepartmentModel> departmentRepository,
            IBaseRepository<JobTitleModel> jobTitleRepository,
            IBaseRepository<HospitalModel> hospitalRepository,
            IBaseRepository<HospitalDepartmentModel> hospitalDepartmentRepository,
            ILogger<GetDoctorsHandler> logger,
            IMapper mapper)
        {
            _doctorRepository = doctorRepository;
            _departmentRepository = departmentRepository;
            _jobTitleRepository = jobTitleRepository;
            _hospitalRepository = hospitalRepository;
            _hospitalDepartmentRepository = hospitalDepartmentRepository;
            _logger = logger;
            _mapper = mapper;
        }

        public async Task<ApiPageing<DoctorDto>> Handle(GetDoctorsCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始获取医生列表，医生姓名：{DoctorName}，科室ID：{DeptId}，职称ID：{JobTitleId}，页码：{PageIndex}，页大小：{PageSize}",
                    request.DoctorName, request.DeptId, request.JobTitleId, request.PageIndex, request.PageSize);

                // 构建查询
                var query = _doctorRepository.GetAll();

                // 应用过滤条件
                if (!string.IsNullOrWhiteSpace(request.DoctorName))
                {
                    query = query.Where(d => d.Doctor_name.Contains(request.DoctorName));
                }

                if (request.DeptId.HasValue)
                {
                    query = query.Where(d => d.Dept_id == request.DeptId.Value);
                }

                if (request.JobTitleId.HasValue)
                {
                    query = query.Where(d => d.JobTitle_id == request.JobTitleId.Value);
                }

                // 计算总记录数
                var totalCount = await query.CountAsync(cancellationToken);

                // 分页查询
                var doctors = await query
                    .OrderBy(d => d.Id)
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .ToListAsync(cancellationToken);

                // 获取相关数据
                var departmentIds = doctors.Select(d => d.Dept_id).Distinct().ToList();
                var jobTitleIds = doctors.Select(d => d.JobTitle_id).Distinct().ToList();

                // 查询科室信息
                var departments = await _departmentRepository.GetAll()
                    .Where(d => departmentIds.Contains(d.Id))
                    .ToDictionaryAsync(d => d.Id, d => d, cancellationToken);

                // 查询职称信息
                var jobTitles = await _jobTitleRepository.GetAll()
                    .Where(j => jobTitleIds.Contains(j.Id))
                    .ToDictionaryAsync(j => j.Id, j => j, cancellationToken);

                // 查询医院科室关系
                var hospitalDepartments = await _hospitalDepartmentRepository.GetAll()
                    .Where(hd => departmentIds.Contains(hd.DepartmentId))
                    .ToListAsync(cancellationToken);

                // 获取相关医院ID
                var hospitalIds = hospitalDepartments.Select(hd => hd.HospitalId).Distinct().ToList();

                // 查询医院信息
                var hospitals = await _hospitalRepository.GetAll()
                    .Where(h => hospitalIds.Contains(h.Id))
                    .ToDictionaryAsync(h => h.Id, h => h, cancellationToken);

                // 创建科室ID到医院的映射
                var departmentToHospital = new Dictionary<int, HospitalModel>();
                foreach (var hd in hospitalDepartments)
                {
                    if (hospitals.TryGetValue(hd.HospitalId, out var hospital))
                    {
                        departmentToHospital[hd.DepartmentId] = hospital;
                    }
                }

                // 转换为DTO
                var doctorDtos = new List<DoctorDto>();
                foreach (var doctor in doctors)
                {
                    var dto = _mapper.Map<DoctorDto>(doctor);
                    
                    // 设置科室名称
                    if (departments.TryGetValue(doctor.Dept_id, out var department))
                    {
                        dto.DepartmentName = department.DepartmentName;
                    }
                    else
                    {
                        dto.DepartmentName = "未知科室";
                    }
                    
                    // 设置职称名称
                    if (jobTitles.TryGetValue(doctor.JobTitle_id, out var jobTitle))
                    {
                        dto.JobTitleName = jobTitle.JobTitle;
                    }
                    else
                    {
                        dto.JobTitleName = "未知职称";
                    }

                    // 设置医院信息
                    if (departmentToHospital.TryGetValue(doctor.Dept_id, out var hospital))
                    {
                        dto.HospitalId = hospital.Id;
                        dto.HospitalName = hospital.HospitalName ?? "未知医院名称";
                    }
                    else
                    {
                        dto.HospitalId = 0;
                        dto.HospitalName = "未知医院";
                    }

                    doctorDtos.Add(dto);
                }

                // 计算总页数
                var totalPages = (int)Math.Ceiling(totalCount / (double)request.PageSize);

                return new ApiPageing<DoctorDto>
                {
                    Code = ApiEnum.Success,
                    Msg = "获取医生列表成功",
                    Data = null, // 不需要设置Data
                    TotaCount = totalCount,
                    TotaPage = totalPages,
                    PageData = doctorDtos
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取医生列表时发生异常");
                return new ApiPageing<DoctorDto>
                {
                    Code = ApiEnum.Error,
                    Msg = "获取医生列表失败：" + ex.Message,
                    PageData = new List<DoctorDto>()
                };
            }
        }
    }
} 